Implement the std::pair parts of "Improving pair and tuple". Completes N4387. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@276605 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/utility b/include/utility index 456a5f7..fbb06f3 100644 --- a/include/utility +++ b/include/utility 
@@ -291,6 +291,7 @@  constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();  #endif   +  template <class _T1, class _T2>  struct _LIBCPP_TYPE_VIS_ONLY pair  { @@ -300,28 +301,6 @@  _T1 first;  _T2 second;   -#ifndef _LIBCPP_HAS_NO_DEFAULT_FUNCTION_TEMPLATE_ARGS - template <bool _Dummy = true, class = typename enable_if< - __dependent_type<is_default_constructible<_T1>, _Dummy>::value && - __dependent_type<is_default_constructible<_T2>, _Dummy>::value - >::type> -#endif - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR pair() : first(), second() {} - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(const _T1& __x, const _T2& __y) - : first(__x), second(__y) {} - - template<class _U1, class _U2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(const pair<_U1, _U2>& __p -#ifndef _LIBCPP_HAS_NO_ADVANCED_SFINAE - ,typename enable_if<is_convertible<const _U1&, _T1>::value && - is_convertible<const _U2&, _T2>::value>::type* = 0 -#endif - ) - : first(__p.first), second(__p.second) {} -  #if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)  _LIBCPP_INLINE_VISIBILITY  pair(const pair& __p) @@ -348,23 +327,172 @@  // Use the implicitly declared copy constructor in C++03  #endif   -#if !defined(_LIBCPP_CXX03_LANG) - typedef typename conditional< - is_copy_assignable<_T1>::value - && is_copy_assignable<_T2>::value, - pair, __nat - >::type _CopyAssignT; - typedef typename conditional< - is_move_assignable<_T1>::value - && is_move_assignable<_T2>::value, - pair, __nat - >::type _MoveAssignT; -#else - typedef pair _CopyAssignT; -#endif +#ifdef _LIBCPP_CXX03_LANG + _LIBCPP_INLINE_VISIBILITY + pair() : first(), second() {}    _LIBCPP_INLINE_VISIBILITY - pair& operator=(_CopyAssignT const& __p) + pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {} + + template <class _U1, class _U2> + _LIBCPP_INLINE_VISIBILITY + pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {} + + _LIBCPP_INLINE_VISIBILITY + pair& operator=(pair const& __p) { + first = __p.first; + second = __p.second; + return *this; + } +#else + template <bool _Val> + using _EnableB = typename enable_if<_Val, bool>::type; + + struct _CheckArgs { + template <class _U1, class _U2> + static constexpr bool __enable_default() { + return is_default_constructible<_U1>::value + && is_default_constructible<_U2>::value; + } + + template <class _U1, class _U2> + static constexpr bool __enable_explicit() { + return is_constructible<first_type, _U1>::value + && is_constructible<second_type, _U2>::value + && (!is_convertible<_U1, first_type>::value + || !is_convertible<_U2, second_type>::value); + } + + template <class _U1, class _U2> + static constexpr bool __enable_implicit() { + return is_constructible<first_type, _U1>::value + && is_constructible<second_type, _U2>::value + && is_convertible<_U1, first_type>::value + && is_convertible<_U2, second_type>::value; + } + }; + + template <bool _MaybeEnable> + using _CheckArgsDep = typename conditional< + _MaybeEnable, _CheckArgs, __check_tuple_constructor_fail>::type; + + struct _CheckTupleLikeConstructor { + template <class _Tuple> + static constexpr bool __enable_implicit() { + return __tuple_convertible<_Tuple, pair>::value; + } + + template <class _Tuple> + static constexpr bool __enable_explicit() { + return __tuple_constructible<_Tuple, pair>::value + && !__tuple_convertible<_Tuple, pair>::value; + } + + template <class _Tuple> + static constexpr bool __enable_assign() { + return __tuple_assignable<_Tuple, pair>::value; + } + }; + + template <class _Tuple> + using _CheckTLC = typename conditional< + __tuple_like_with_size<_Tuple, 2>::value + && !is_same<typename decay<_Tuple>::type, pair>::value, + _CheckTupleLikeConstructor, + __check_tuple_constructor_fail + >::type; + + template<bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_default<_T1, _T2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR + pair() : first(), second() {} + + template <bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_explicit<_T1 const&, _T2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_T1 const& __t1, _T2 const& __t2) + : first(__t1), second(__t2) {} + + template<bool _Dummy = true, _EnableB< + _CheckArgsDep<_Dummy>::template __enable_implicit<_T1 const&, _T2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_T1 const& __t1, _T2 const& __t2) + : first(__t1), second(__t2) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_U1&& __u1, _U2&& __u2) + : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_U1&& __u1, _U2&& __u2) + : first(_VSTD::forward<_U1>(__u1)), second(_VSTD::forward<_U2>(__u2)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1 const&, _U2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(pair<_U1, _U2> const& __p) + : first(__p.first), second(__p.second) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1 const&, _U2 const&>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(pair<_U1, _U2> const& __p) + : first(__p.first), second(__p.second) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_explicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(pair<_U1, _U2>&&__p) + : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} + + template<class _U1, class _U2, _EnableB< + _CheckArgs::template __enable_implicit<_U1, _U2>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(pair<_U1, _U2>&& __p) + : first(_VSTD::forward<_U1>(__p.first)), second(_VSTD::forward<_U2>(__p.second)) {} + + template<class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_explicit<_Tuple>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit pair(_Tuple&& __p) + : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), + second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} + + template<class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_implicit<_Tuple>() + > = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + pair(_Tuple&& __p) + : first(_VSTD::get<0>(_VSTD::forward<_Tuple>(__p))), + second(_VSTD::get<1>(_VSTD::forward<_Tuple>(__p))) {} + + template <class... _Args1, class... _Args2> + _LIBCPP_INLINE_VISIBILITY + pair(piecewise_construct_t __pc, + tuple<_Args1...> __first_args, tuple<_Args2...> __second_args) + : pair(__pc, __first_args, __second_args, + typename __make_tuple_indices<sizeof...(_Args1)>::type(), + typename __make_tuple_indices<sizeof...(_Args2) >::type()) {} + + _LIBCPP_INLINE_VISIBILITY + pair& operator=(typename conditional< + is_copy_assignable<first_type>::value && + is_copy_assignable<second_type>::value, + pair, __nat>::type const& __p)  _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&  is_nothrow_copy_assignable<second_type>::value)  { @@ -373,9 +501,11 @@  return *this;  }   -#ifndef _LIBCPP_CXX03_LANG  _LIBCPP_INLINE_VISIBILITY - pair& operator=(_MoveAssignT&& __p) + pair& operator=(typename conditional< + is_move_assignable<first_type>::value && + is_move_assignable<second_type>::value, + pair, __nat>::type&& __p)  _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&  is_nothrow_move_assignable<second_type>::value)  { @@ -383,68 +513,18 @@  second = _VSTD::forward<second_type>(__p.second);  return *this;  } + + template <class _Tuple, _EnableB< + _CheckTLC<_Tuple>::template __enable_assign() + > = false> + _LIBCPP_INLINE_VISIBILITY + pair& operator=(_Tuple&& __p) { + first = _VSTD::get<0>(_VSTD::forward<_Tuple>(__p)); + second = _VSTD::get<1>(_VSTD::forward<_Tuple>(__p)); + return *this; + }  #endif   -#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - - template <class _U1, class _U2, - class = typename enable_if<is_convertible<_U1, first_type>::value && - is_convertible<_U2, second_type>::value>::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(_U1&& __u1, _U2&& __u2) - : first(_VSTD::forward<_U1>(__u1)), - second(_VSTD::forward<_U2>(__u2)) - {} - - template<class _U1, class _U2> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(pair<_U1, _U2>&& __p, - typename enable_if<is_convertible<_U1, _T1>::value && - is_convertible<_U2, _T2>::value>::type* = 0) - : first(_VSTD::forward<_U1>(__p.first)), - second(_VSTD::forward<_U2>(__p.second)) {} - - - -#ifndef _LIBCPP_HAS_NO_VARIADICS - template<class _Tuple, - class = typename enable_if<__tuple_convertible<_Tuple, pair>::value>::type> - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 - pair(_Tuple&& __p) - : first(_VSTD::forward<typename tuple_element<0, - typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<0>(__p))), - second(_VSTD::forward<typename tuple_element<1, - typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<1>(__p))) - {} - - - - template <class... _Args1, class... _Args2> - _LIBCPP_INLINE_VISIBILITY - pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, - tuple<_Args2...> __second_args) - : pair(__pc, __first_args, __second_args, - typename __make_tuple_indices<sizeof...(_Args1)>::type(), - typename __make_tuple_indices<sizeof...(_Args2) >::type()) - {} - - template <class _Tuple, - class = typename enable_if<!is_same<typename decay<_Tuple>::type, pair>::value && __tuple_assignable<_Tuple, pair>::value>::type> - _LIBCPP_INLINE_VISIBILITY - pair& - operator=(_Tuple&& __p) - { - typedef typename __make_tuple_types<_Tuple>::type _TupleRef; - typedef typename tuple_element<0, _TupleRef>::type _U0; - typedef typename tuple_element<1, _TupleRef>::type _U1; - first = _VSTD::forward<_U0>(_VSTD::get<0>(__p)); - second = _VSTD::forward<_U1>(_VSTD::get<1>(__p)); - return *this; - } - -#endif // _LIBCPP_HAS_NO_VARIADICS - -#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES  _LIBCPP_INLINE_VISIBILITY  void  swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value && @@ -456,13 +536,13 @@  }  private:   -#ifndef _LIBCPP_HAS_NO_VARIADICS +#ifndef _LIBCPP_CXX03_LANG  template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>  _LIBCPP_INLINE_VISIBILITY  pair(piecewise_construct_t,  tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,  __tuple_indices<_I1...>, __tuple_indices<_I2...>); -#endif // _LIBCPP_HAS_NO_VARIADICS +#endif  };    template <class _T1, class _T2>